package xyz.jcat.generator.mybatis;

import xyz.jcat.common.util.StringUtils;
import xyz.jcat.generator.mybatis.bo.JavaField;
import xyz.jcat.generator.mybatis.bo.JavaInfo;
import xyz.jcat.generator.mybatis.config.DbConfig;
import xyz.jcat.generator.mybatis.config.DbConfig.DBInfo;
import xyz.jcat.generator.mybatis.config.JavaType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import xyz.jcat.generator.mybatis.convert.ITypeConvert;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * @author yueyue
 * @Time 2017-05-15 16:52
 */
@Slf4j
@Repository
public class TableInfoDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 获取表名
     *
     * @param dbConfig
     * @return
     */
    public List<String> tableList(DbConfig dbConfig) {
        String sql = dbConfig.getDbInfo().getQueryTablesSql();
        log.info("获取表名SQL -> {}", sql);
        return jdbcTemplate.queryForList(sql, String.class);
    }

    /**
     * 获取表信息
     *
     * @param tableName
     * @param dbConfig
     * @return
     */
    public JavaInfo javaFileInfo(String tableName, DbConfig dbConfig) {
        JavaInfo javaInfo = new JavaInfo();
        DbConfig.DBInfo dbInfo = dbConfig.getDbInfo();
        ITypeConvert typeConvert = dbConfig.getTypeConvert();
        String sql = String.format(dbInfo.getQueryTableInfoSql(), tableName);
        log.info("获取表信息SQL -> {}", sql);
        MapRowMapper.dbInfo = dbInfo;
        List<Map<String, Object>> fields = jdbcTemplate.query(sql, new MapRowMapper());
        List<JavaField> javaFieldList = new ArrayList<JavaField>();
        javaInfo.setImportList(new TreeSet<>());
        for (Map<String, Object> field : fields) {
            JavaField javaField = new JavaField();
            String dbTypeName = (String) field.get(dbInfo.getFieldTypeName());
            JavaType javaType = typeConvert.javaTypeConvert(dbTypeName);
            if (StringUtils.isNotEmpty(javaType.getPkg())) {
                javaInfo.getImportList().add(javaType.getPkg());
            }
            javaField.setDbField((String) field.get(dbInfo.getFieldName()));
            javaField.setBeanType(javaType.getType());
            javaField.setPk(dbInfo.getPkName().equals(field.get(dbInfo.getKeyName())));
            javaField.setComment((String) field.get(dbInfo.getComment()));
            javaField.setDefaultValue(field.get(dbInfo.getDefaultName()));
            javaFieldList.add(javaField);
        }
        javaInfo.setTableName(tableName);
        javaInfo.setFieldsList(javaFieldList);
        return javaInfo;
    }

    public static class MapRowMapper implements RowMapper<Map<String, Object>> {

        public static DBInfo dbInfo;

        @Override
        public Map<String, Object> mapRow(ResultSet resultSet, int i) throws SQLException {
            Map<String, Object> map = new HashMap<>();
            map.put(dbInfo.getFieldName(), resultSet.getString(dbInfo.getFieldName()));
            map.put(dbInfo.getFieldTypeName(), resultSet.getString(dbInfo.getFieldTypeName()));
            map.put(dbInfo.getKeyName(), resultSet.getString(dbInfo.getKeyName()));
            map.put(dbInfo.getComment(), resultSet.getString(dbInfo.getComment()));
            map.put(dbInfo.getDefaultName(), resultSet.getString(dbInfo.getDefaultName()));
            return map;
        }
    }
}
